package Code.Basic.AI.Pathfinding;

import java.util.ArrayList;
import java.util.HashMap;

import org.jrabbit.base.graphics.transforms.Vector2d;

import Code.Basic.Entity.GenericCharacter;

public class OpenZone extends Zone
{
	private ZoneConnection[] connections;
	private ArrayList<HotZone> hotZones;
	private HashMap<OpenZone, OpenZone[]> paths;
	private PathMap map;
	
	public OpenZone(double[][] pointArray)
	{
		super(pointArray);
		connections = new ZoneConnection[0];
		paths = new HashMap<OpenZone, OpenZone[]>();
	}
	
	public void setZoneConnections(ZoneConnection[] connects)
	{
		connections = connects;
	}
	
	public void setPathTo(OpenZone target, OpenZone[] path)
	{
		paths.put(target, path);
	}
	
	public void calculatePaths() 
	{		
		for(OpenZone tempZone:map.getOpenZones())
		{
			if (tempZone != this)
			{
				paths.put(tempZone, map.findPath(this, tempZone));
			}
		}
	}
	
	public OpenZone[] getPathTo(OpenZone destination)
	{
		return paths.get(destination);
	}
	
	// what to do when a character enters this zone
	// the character will call this method
	public void characterEnteredZone(GenericCharacter c)
	{
		
	}
	
	// what to do when a character leaves this zone
	// the character will call this method
	public void characterExitedZone(GenericCharacter c)
	{
		
	}
	
	public void addConnectedZone(OpenZone zone, long moveCost, double[] ends)
	{
		ZoneConnection[] newConnections = new ZoneConnection[connections.length + 1];
		for(int i = 0; i < connections.length; i++)
		{
			newConnections[i] = connections[i];
		}
		newConnections[connections.length] = new ZoneConnection(zone, moveCost, ends);
		connections = newConnections;
	}
	
	public ZoneConnection[] getConnectedZones()
	{
		return connections;
	}
	
	public void addHotZone(HotZone zone)
	{
		hotZones.add(zone);
	}
	
	public ArrayList<HotZone> getHotZones()
	{
		return hotZones;
	}
	
	public long getHValue(OpenZone end)
	{
		return 0;
	}
	
	public long getBonusGValues()
	{
		return 0;
	}
	
	public boolean characterIsInZone(GenericCharacter c)
	{
		return geometry.containsPoint(c.location());
	}
	
	public Vector2d genEndPoint(double x, double y, double endX, double endY, OpenZone previous)
	{
		Vector2d finalPoint = null;
		for (int i = 0; i < connections.length; i++)
		{
			if ((connections[i].getConnectedZone() == null) || (connections[i].getConnectedZone() != previous))
			{
				// find the point of intersection
				double x11 = x;
				double y1 = y;
				double x21 = connections[i].getEndPoints()[0];
				double y2 = connections[i].getEndPoints()[1];
				double x22 = connections[i].getEndPoints()[2];
				double y22 = connections[i].getEndPoints()[3];
				double intersectX = ((((endY - y) / (endX - x)) * x11) - y1 - (((y22 - y2)
									/ (x22 - x21)) * x21) + y2) / (((endY - y) / (endX - x))
									- ((y22 - y2) / (x22 - x21)));
				double intersectY = (((endY - y) / (endX - x)) * (intersectX - x)) + y;
				
				// find if the point is past the cursor
				if (x >= endX)
				{
					finalPoint = new Vector2d(endX, endY);
				}
				// find if the point is on a connection
				else if (connections[i].getConnectedZone() != null)
				{
					finalPoint = connections[i].getConnectedZone().genEndPoint(intersectX, intersectY, endX, endY, this);
				}
				// find if the point should stop
				else if (connections[i].getConnectedZone() == null)
				{
					finalPoint = new Vector2d(intersectX, intersectY);
				}
			}
		}
		return finalPoint;
	}
}